{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "47574490",
   "metadata": {},
   "source": [
    "# Simulate the ground state of a Hydrogen molecule using Variational Quantum Eigensolver (VQE) on the Quantinuum emulator\n",
    "\n",
    "![Hydrogen molecule](https://user-images.githubusercontent.com/4041805/166981145-c33b8d1a-24d1-4776-91ee-f514b0a5ab04.jpg)\n",
    "\n",
    "In this notebook, you'll learn how to run VQE for a $H_{2}$ molecule on the Quantinuum emulator using Qiskit on an Azure Quantum backend.\n",
    "\n",
    "VQE is a variational algorithm for quantum chemistry that uses an optimization loop to minimize a cost function. The cost function is an energy evaluation $E = <\\psi|H|\\psi>$ where $|\\psi (\\theta)>$ is a parametric trial state that estimates the ground state of the molecule. For each evaluation, we modify the trial state until the energy reaches a minimum.\n",
    "\n",
    "![VQE diagram](https://user-images.githubusercontent.com/4041805/166981008-023aba4c-26f8-498e-93ee-a1d9a39ddbcd.png)\n",
    "\n",
    "For more information about running VQE using Qiskit, see: [Qiskit Textbook - VQE Molecules](https://qiskit.org/textbook/ch-applications/vqe-molecules.html#implementationnoisy).\n",
    "\n",
    "To read more about the optimization method used in this example, see [Wikipedia - SPSA](https://en.wikipedia.org/wiki/Simultaneous_perturbation_stochastic_approximation)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f361a714",
   "metadata": {},
   "source": [
    "Before geting started, you need to import the required packages."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "71d2cb0b",
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "\n",
    "from qiskit import IBMQ, BasicAer, Aer\n",
    "from qiskit.aqua import QuantumInstance\n",
    "from qiskit.aqua.components.optimizers import COBYLA, SPSA, SLSQP\n",
    "from qiskit.aqua.operators import Z2Symmetries\n",
    "from qiskit.aqua.algorithms import VQE, NumPyEigensolver\n",
    "from qiskit.chemistry.components.variational_forms import UCCSD\n",
    "from qiskit.chemistry.components.initial_states import HartreeFock\n",
    "from qiskit.circuit.library import EfficientSU2\n",
    "from qiskit.chemistry.drivers import PySCFDriver, UnitsType\n",
    "from qiskit.chemistry import FermionicOperator\n",
    "from qiskit.ignis.mitigation.measurement import CompleteMeasFitter\n",
    "from qiskit.providers.aer.noise import NoiseModel"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7dadd1bf",
   "metadata": {},
   "source": [
    "First, prepare the qubit operators to get the one-body and two-body integrals that encode the Hydrogen molecule and map them onto qubits using Quantum gates.\n",
    "\n",
    "You'll use [PySCF](https://github.com/pyscf/pyscf) to generate the molecule, and [Qiskit Chemistry](https://quantum-computing.ibm.com/lab/docs/iql/chemistry) to encode it into Fermionic operators."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "9b4ce39a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a PySCF driver an generate the molecule\n",
    "driver = PySCFDriver(atom='H .0 .0 -0.3625; H .0 .0 0.3625', unit=UnitsType.ANGSTROM, charge=0, spin=0, basis='sto3g')\n",
    "molecule = driver.run()\n",
    "# Get the total number of particles in the molecule\n",
    "num_particles = molecule.num_alpha + molecule.num_beta\n",
    "# Convert one-body and two-body integrals into fermionic operators\n",
    "qubit_op = FermionicOperator(h1=molecule.one_body_integrals, h2=molecule.two_body_integrals).mapping(map_type='parity')\n",
    "qubit_op = Z2Symmetries.two_qubit_reduction(qubit_op, num_particles)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50174a98",
   "metadata": {},
   "source": [
    "## 1. Simulate locally\n",
    "\n",
    "Here, you will simulate the program locally using the Aer simulator. You can create a `QuantumInstance` with a noise model using a mock device `FakeVigo` with noise characteristics."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "737c1000",
   "metadata": {},
   "outputs": [],
   "source": [
    "from qiskit.test.mock import FakeVigo\n",
    "from qiskit.providers.aer import AerSimulator\n",
    "from qiskit.providers.aer import QasmSimulator\n",
    "from qiskit.providers.aer.noise import NoiseModel\n",
    "\n",
    "backend = AerSimulator()\n",
    "device_backend = FakeVigo()\n",
    "device = QasmSimulator.from_backend(device_backend)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9939a47",
   "metadata": {},
   "source": [
    "Then, run the simulation using the VQE class."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4ffa5a4",
   "metadata": {},
   "source": [
    "### Simulate locally with noise and error mitigation\n",
    "\n",
    "You can read more about error mitigation in the Qiskit textbook chapter on [Measurement Error Mitigation](https://qiskit.org/textbook/ch-quantum-hardware/measurement-error-mitigation.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "b4788b3c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Exact Result: [-1.13722138]\n",
      "VQE Result on noisy simulator: -1.0980120899310355\n"
     ]
    }
   ],
   "source": [
    "# Create the noise characteristics and other parameters that describe the device\n",
    "coupling_map = device.configuration().coupling_map\n",
    "noise_model = NoiseModel.from_backend(device)\n",
    "basis_gates = noise_model.basis_gates\n",
    "\n",
    "# Create the quantum instance to conncet to the backend\n",
    "quantum_instance = QuantumInstance(backend=backend, \n",
    "                                   shots=8192, \n",
    "                                   noise_model=noise_model, \n",
    "                                   coupling_map=coupling_map,\n",
    "                                   measurement_error_mitigation_cls=CompleteMeasFitter,\n",
    "                                   cals_matrix_refresh_period=30)\n",
    "\n",
    "# Calculate the exact solution using numpy\n",
    "exact_solution = NumPyEigensolver(qubit_op).run()\n",
    "print(\"Exact Result:\", np.real(exact_solution.eigenvalues) + molecule.nuclear_repulsion_energy)\n",
    "\n",
    "# Create an optimizer (using SPSA)\n",
    "optimizer = SPSA(maxiter=100)\n",
    "\n",
    "# Create the variational form\n",
    "var_form = EfficientSU2(qubit_op.num_qubits, entanglement=\"linear\")\n",
    "\n",
    "# Create a VQE object that runs VQE using the above created qubit operations, variational form and optimizer\n",
    "vqe = VQE(qubit_op, var_form, optimizer=optimizer)\n",
    "\n",
    "# Run the full VQE program\n",
    "ret = vqe.run(quantum_instance)\n",
    "\n",
    "# Get and print the result\n",
    "vqe_result = np.real(ret['eigenvalue'] + molecule.nuclear_repulsion_energy)\n",
    "print(\"VQE Result on noisy simulator:\", vqe_result)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84237dc8",
   "metadata": {},
   "source": [
    "The parameters found by the optimization loop:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "77f373f5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 0.88146786,  2.14943478, -0.84908566,  1.72896896, -1.57937698,\n",
       "        0.00403366,  2.67581075,  0.99780415, -1.25767836,  1.28513983,\n",
       "        0.99229133,  1.02959351, -0.82504384, -0.44857987, -2.32099255,\n",
       "        0.30197518])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p0 = ret.optimal_point\n",
    "p0"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c4338b61",
   "metadata": {},
   "source": [
    "The energy was evaluated a total of `ret.cost_function_evals` times until the minimum was found."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "9930b2c9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "241"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ret.cost_function_evals"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87005ce0",
   "metadata": {},
   "source": [
    "### Circuit visualization\n",
    "\n",
    "Each energy evaluation consists of two circuits. You can visualize these circuits with Qiskit using the `vqe` instance."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "69e6719e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# The VQE class generates extra unused wires.\n",
    "# This function is to remove idle wires to make the visualization more readable.\n",
    "# See: https://quantumcomputing.stackexchange.com/questions/25672/remove-inactive-qubits-from-qiskit-circuit\n",
    "from qiskit.converters import circuit_to_dag, dag_to_circuit\n",
    "from collections import OrderedDict\n",
    "\n",
    "def remove_idle_qwires(circ):\n",
    "    dag = circuit_to_dag(circ)\n",
    "\n",
    "    idle_wires = list(dag.idle_wires())\n",
    "    for w in idle_wires:\n",
    "        dag._remove_idle_wire(w)\n",
    "        dag.qubits.remove(w)\n",
    "\n",
    "    dag.qregs = OrderedDict()\n",
    "\n",
    "    return dag_to_circuit(dag)\n",
    "\n",
    "circs = vqe._circuit_sampler._transpiled_circ_cache\n",
    "circs = [remove_idle_qwires(circ) for circ in circs]\n",
    "circ = circs[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "e0ab0e41",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"word-wrap: normal;white-space: pre;background: #fff0;line-height: 1.1;font-family: &quot;Courier New&quot;,Courier,monospace\">      ┌──────────┐┌──────────┐     ┌──────────┐┌──────────┐     ┌──────────┐»\n",
       "   0: ┤ Ry(θ[0]) ├┤ Rz(θ[2]) ├──■──┤ Ry(θ[4]) ├┤ Rz(θ[6]) ├──■──┤ Ry(θ[8]) ├»\n",
       "      ├──────────┤├──────────┤┌─┴─┐├──────────┤├──────────┤┌─┴─┐├──────────┤»\n",
       "   1: ┤ Ry(θ[1]) ├┤ Rz(θ[3]) ├┤ X ├┤ Ry(θ[5]) ├┤ Rz(θ[7]) ├┤ X ├┤ Ry(θ[9]) ├»\n",
       "      └──────────┘└──────────┘└───┘└──────────┘└──────────┘└───┘└──────────┘»\n",
       "c0: 2/══════════════════════════════════════════════════════════════════════»\n",
       "                                                                            »\n",
       "«      ┌───────────┐     ┌───────────┐┌───────────┐┌───┐┌─┐   \n",
       "«   0: ┤ Rz(θ[10]) ├──■──┤ Ry(θ[12]) ├┤ Rz(θ[14]) ├┤ H ├┤M├───\n",
       "«      ├───────────┤┌─┴─┐├───────────┤├───────────┤├───┤└╥┘┌─┐\n",
       "«   1: ┤ Rz(θ[11]) ├┤ X ├┤ Ry(θ[13]) ├┤ Rz(θ[15]) ├┤ H ├─╫─┤M├\n",
       "«      └───────────┘└───┘└───────────┘└───────────┘└───┘ ║ └╥┘\n",
       "«c0: 2/══════════════════════════════════════════════════╩══╩═\n",
       "«                                                        0  1 </pre>"
      ],
      "text/plain": [
       "      ┌──────────┐┌──────────┐     ┌──────────┐┌──────────┐     ┌──────────┐»\n",
       "   0: ┤ Ry(θ[0]) ├┤ Rz(θ[2]) ├──■──┤ Ry(θ[4]) ├┤ Rz(θ[6]) ├──■──┤ Ry(θ[8]) ├»\n",
       "      ├──────────┤├──────────┤┌─┴─┐├──────────┤├──────────┤┌─┴─┐├──────────┤»\n",
       "   1: ┤ Ry(θ[1]) ├┤ Rz(θ[3]) ├┤ X ├┤ Ry(θ[5]) ├┤ Rz(θ[7]) ├┤ X ├┤ Ry(θ[9]) ├»\n",
       "      └──────────┘└──────────┘└───┘└──────────┘└──────────┘└───┘└──────────┘»\n",
       "c0: 2/══════════════════════════════════════════════════════════════════════»\n",
       "                                                                            »\n",
       "«      ┌───────────┐     ┌───────────┐┌───────────┐┌───┐┌─┐   \n",
       "«   0: ┤ Rz(θ[10]) ├──■──┤ Ry(θ[12]) ├┤ Rz(θ[14]) ├┤ H ├┤M├───\n",
       "«      ├───────────┤┌─┴─┐├───────────┤├───────────┤├───┤└╥┘┌─┐\n",
       "«   1: ┤ Rz(θ[11]) ├┤ X ├┤ Ry(θ[13]) ├┤ Rz(θ[15]) ├┤ H ├─╫─┤M├\n",
       "«      └───────────┘└───┘└───────────┘└───────────┘└───┘ ║ └╥┘\n",
       "«c0: 2/══════════════════════════════════════════════════╩══╩═\n",
       "«                                                        0  1 "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ.draw()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5085e0c6",
   "metadata": {},
   "source": [
    "This visualization shows the parametric trial state that is prepared and evaluated as part of VQE. The parameters, $\\theta[n]$, are assigned a value for each iteration."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6dd36770",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"word-wrap: normal;white-space: pre;background: #fff0;line-height: 1.1;font-family: &quot;Courier New&quot;,Courier,monospace\">       ┌──────────────────────┐┌───────────────────────┐     »\n",
       "   0: ─┤ Ry(0.88146786270954) ├┤ Rz(-1.25767836106238) ├──■──»\n",
       "      ┌┴──────────────────────┤└┬──────────────────────┤┌─┴─┐»\n",
       "   1: ┤ Ry(0.997804153760643) ├─┤ Rz(1.28513982964721) ├┤ X ├»\n",
       "      └───────────────────────┘ └──────────────────────┘└───┘»\n",
       "c0: 2/═══════════════════════════════════════════════════════»\n",
       "                                                             »\n",
       "«      ┌───────────────────────┐┌────────────────────────┐     »\n",
       "«   0: ┤ Ry(0.992291331777119) ├┤ Rz(-0.825043844596012) ├──■──»\n",
       "«      └┬─────────────────────┬┘├────────────────────────┤┌─┴─┐»\n",
       "«   1: ─┤ Ry(1.0295935084448) ├─┤ Rz(-0.448579872331894) ├┤ X ├»\n",
       "«       └─────────────────────┘ └────────────────────────┘└───┘»\n",
       "«c0: 2/════════════════════════════════════════════════════════»\n",
       "«                                                              »\n",
       "«      ┌───────────────────────┐ ┌──────────────────────┐      »\n",
       "«   0: ┤ Ry(-2.32099254965095) ├─┤ Rz(2.14943478014898) ├───■──»\n",
       "«      ├───────────────────────┤┌┴──────────────────────┴┐┌─┴─┐»\n",
       "«   1: ┤ Ry(0.301975180425836) ├┤ Rz(-0.849085656093776) ├┤ X ├»\n",
       "«      └───────────────────────┘└────────────────────────┘└───┘»\n",
       "«c0: 2/════════════════════════════════════════════════════════»\n",
       "«                                                              »\n",
       "«       ┌──────────────────────┐┌─────────────────────────┐┌───┐┌─┐   \n",
       "«   0: ─┤ Ry(1.72896895522764) ├┤ Rz(0.00403365782424605) ├┤ H ├┤M├───\n",
       "«      ┌┴──────────────────────┤└─┬─────────────────────┬─┘├───┤└╥┘┌─┐\n",
       "«   1: ┤ Ry(-1.57937697516976) ├──┤ Rz(2.6758107484427) ├──┤ H ├─╫─┤M├\n",
       "«      └───────────────────────┘  └─────────────────────┘  └───┘ ║ └╥┘\n",
       "«c0: 2/══════════════════════════════════════════════════════════╩══╩═\n",
       "«                                                                0  1 </pre>"
      ],
      "text/plain": [
       "       ┌──────────────────────┐┌───────────────────────┐     »\n",
       "   0: ─┤ Ry(0.88146786270954) ├┤ Rz(-1.25767836106238) ├──■──»\n",
       "      ┌┴──────────────────────┤└┬──────────────────────┤┌─┴─┐»\n",
       "   1: ┤ Ry(0.997804153760643) ├─┤ Rz(1.28513982964721) ├┤ X ├»\n",
       "      └───────────────────────┘ └──────────────────────┘└───┘»\n",
       "c0: 2/═══════════════════════════════════════════════════════»\n",
       "                                                             »\n",
       "«      ┌───────────────────────┐┌────────────────────────┐     »\n",
       "«   0: ┤ Ry(0.992291331777119) ├┤ Rz(-0.825043844596012) ├──■──»\n",
       "«      └┬─────────────────────┬┘├────────────────────────┤┌─┴─┐»\n",
       "«   1: ─┤ Ry(1.0295935084448) ├─┤ Rz(-0.448579872331894) ├┤ X ├»\n",
       "«       └─────────────────────┘ └────────────────────────┘└───┘»\n",
       "«c0: 2/════════════════════════════════════════════════════════»\n",
       "«                                                              »\n",
       "«      ┌───────────────────────┐ ┌──────────────────────┐      »\n",
       "«   0: ┤ Ry(-2.32099254965095) ├─┤ Rz(2.14943478014898) ├───■──»\n",
       "«      ├───────────────────────┤┌┴──────────────────────┴┐┌─┴─┐»\n",
       "«   1: ┤ Ry(0.301975180425836) ├┤ Rz(-0.849085656093776) ├┤ X ├»\n",
       "«      └───────────────────────┘└────────────────────────┘└───┘»\n",
       "«c0: 2/════════════════════════════════════════════════════════»\n",
       "«                                                              »\n",
       "«       ┌──────────────────────┐┌─────────────────────────┐┌───┐┌─┐   \n",
       "«   0: ─┤ Ry(1.72896895522764) ├┤ Rz(0.00403365782424605) ├┤ H ├┤M├───\n",
       "«      ┌┴──────────────────────┤└─┬─────────────────────┬─┘├───┤└╥┘┌─┐\n",
       "«   1: ┤ Ry(-1.57937697516976) ├──┤ Rz(2.6758107484427) ├──┤ H ├─╫─┤M├\n",
       "«      └───────────────────────┘  └─────────────────────┘  └───┘ ║ └╥┘\n",
       "«c0: 2/══════════════════════════════════════════════════════════╩══╩═\n",
       "«                                                                0  1 "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "circ.assign_parameters(ret.optimal_parameters).draw()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d49d174",
   "metadata": {},
   "source": [
    "## 2. Run on Quantinuum emulator via Azure Quantum Workspace\n",
    "\n",
    "Now, you can connect to the Azure Quantum Workspace and run VQE on the hardware backends."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "c042c41e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Connect to the Azure Quantum Workspace via a Qiskit provider\n",
    "from azure.quantum.qiskit import AzureQuantumProvider\n",
    "provider = AzureQuantumProvider(\n",
    "    resource_id = \"\",\n",
    "    location = \"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "592e9d54",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create Quantinuum emulator backend\n",
    "quantinuum_emulator = provider.get_backend(\"quantinuum.sim.h1-1e\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69a3a14c",
   "metadata": {},
   "source": [
    "### Estimate cost\n",
    "\n",
    "You can now estimate how many credits (\"HQC\"/\"EHQC\" for Quantinuum) it will cost to run VQE. For more information about pricing, see the [Azure Quantum pricing](https://docs.microsoft.com/azure/quantum/pricing) documentation page."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "ed975803",
   "metadata": {},
   "outputs": [],
   "source": [
    "cost = [quantinuum_emulator.estimate_cost(circ.assign_parameters(ret.optimal_parameters), shots=1000) for circ in circs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "9edf5289",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "16.6 EHQC\n",
      "16.2 EHQC\n"
     ]
    }
   ],
   "source": [
    "for _cost in cost:\n",
    "    print(_cost.estimated_total, _cost.currency_code)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8924df25",
   "metadata": {},
   "source": [
    "So, given approx. 300 energy evaluations, this would give a total cost"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "627268da",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Single iteration: 32.8 EHQC, 300 iterations: 9840.0 EHQC\n"
     ]
    }
   ],
   "source": [
    "num_iterations = 300\n",
    "energy_eval_cost = sum(_cost.estimated_total for _cost in cost)\n",
    "print(f\"Single iteration: {energy_eval_cost} {_cost.currency_code}, {num_iterations} iterations: {energy_eval_cost * num_iterations} {_cost.currency_code}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c478eaa4",
   "metadata": {},
   "source": [
    "To get a visual on the circuit width and depth, run:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "cb9c3998",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "width | depth\n",
      "4 13\n",
      "4 13\n"
     ]
    }
   ],
   "source": [
    "print(\"width | depth\")\n",
    "for circuit in circs:\n",
    "    circuit = circ.assign_parameters(ret.optimal_parameters)\n",
    "    circuit = remove_idle_qwires(circuit)\n",
    "    print(circuit.width(), circuit.depth())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc8a8b3e",
   "metadata": {},
   "source": [
    "### Run one iteration on Quantinuum emulator via Azure Quantum\n",
    "\n",
    "It can take a long time to run a full VQE program on hardware, because each iteration puts a circuit in the queue. For demonstration purposes, you can run only the last iteration using the parameters we found with the Aer simulator."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "cedb793f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is a bug that will be addressed in this PR: https://github.com/microsoft/qdk-python/pull/301\n",
    "quantinuum_emulator.configuration().max_shots = None"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "a8c69fa4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create Quantum Instance to connect to the backend\n",
    "quantum_instance = QuantumInstance(backend=quantinuum_emulator,\n",
    "                                   shots=8192)\n",
    "# Unset qjob config to avoid errors when running job.result()\n",
    "quantum_instance._qjob_config = {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "aa220dee",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create optimizer with only one iteration\n",
    "optimizer = SPSA(maxiter=1)\n",
    "# Create the variational form of the ansatz\n",
    "var_form = EfficientSU2(qubit_op.num_qubits, entanglement=\"linear\")\n",
    "# Create a VQE object that runs the algorithm\n",
    "vqe = VQE(qubit_op, var_form, optimizer=optimizer)\n",
    "# Set the quantum instance to be able to run only the last iteration\n",
    "vqe.quantum_instance = quantum_instance"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ecddf94a",
   "metadata": {},
   "source": [
    "The below cell will evaluate the energy at `p0` using the Quantinuum emulator.\n",
    "\n",
    "You have to add the molecular nuclear repulsion energy to the final result to get the ground state of the molecule."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "659ed1a0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".....................\n",
      "\n",
      "-1.1198872295256754\n"
     ]
    }
   ],
   "source": [
    "vqe._energy_evaluation(parameters=p0) + molecule.nuclear_repulsion_energy"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a91f4a4",
   "metadata": {},
   "source": [
    "In this notebook, you've run a single iteration of VQE on an Azure Quantum backend to calculate the ground state of a $H_2$ molecule. Nice job! 👏🏽\n",
    "\n",
    "As a next step, you can modify the sample to run your own molecule, or run it on hardware."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
